package no.ntnu.idi.deid.documentunits;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import org.annolab.tt4j.TreeTaggerException;

import no.ntnu.idi.deid.config.Constants;
import no.ntnu.idi.deid.preprocessor.tokenizer.Tokenizer;
import no.ntnu.idi.deid.preprocessor.wordcount.CountManager;
import no.ntnu.idi.deid.preprocessor.wordcount.SentenceCountManager;
import no.ntnu.idi.deid.preprocessor.wordcount.WordCountManager;

import no.ntnu.idi.deid.preprocessor.PreRuleBase;
import no.ntnu.idi.deid.preprocessor.postagger.POSTag;

/*
 * 
 * Samleobjekt med alle typer preprocessing-elementer per dokument. Dette objektet sendes til DocumentPreProcessor.java klassen
 * der all data fra alle dokumenter samles. Hele denne smæla sendes deretter til neste modul!
 *  
 */

public class Document extends ArrayList<Section>{
	
	private static final long serialVersionUID = 1L;
	//Files and folders
	private String sentenizedInputFilePath;
	private String posTagfilePath;
	
	private int id;
	
	//indexes used to assign ID's, and get incremented each time new token/sentence/section-instances are created.
	private static int tokenIndex;
	private static int sentenceIndex;
	private static int sectionIndex;
//	private List<Token> allTokens;
	
	//Only used for word count purpose
	private CountManager wcm;
	private CountManager scm;
	
	
	public Document(int id, String sentenizedinputPath, String posTagPath) throws IOException, TreeTaggerException{
		tokenIndex = sentenceIndex = sectionIndex = 0;
		this.id = id;
		sentenizedInputFilePath = sentenizedinputPath;
		posTagfilePath = posTagPath;
		makeSections();
		assignPosTagsToTokens(posTagfilePath);
		prepareTokens();
		setParents();
		
	}
	
	public String getName() {
		File file = new File(sentenizedInputFilePath);
		return file.getName().substring(4);
	}
	
	
	private void setParents() {
		for(Section section: this) {
			section.setParent(this);
		}
	}

	private void makeSections() throws FileNotFoundException{
		try{
			Scanner sc = new Scanner(new File(sentenizedInputFilePath));
			String line = "";
			while(sc.hasNextLine()){
				List<Sentence> section = new ArrayList<>();
				line = sc.nextLine();
				while(!line.equals(Constants.SECTION_SPLITTER) && sc.hasNextLine()){
					if(!line.isEmpty()){
						section.add(Sentence.makeSentence(line));
						line = sc.nextLine();
					}
				}
				if(!line.equals(Constants.SECTION_SPLITTER) && !sc.hasNextLine()){
					if(!line.isEmpty()){
						section.add(Sentence.makeSentence(line));
					}
				}
				if(!section.isEmpty()){
					add(new Section(getAndIncreaseSectionIndex(),section));
					section = new ArrayList<Sentence>();
				}
			}
			sc.close();
		}catch (FileNotFoundException e){
			System.err.println(e.getMessage());
		}
	}
	
	public CountManager getSentenceCountManager() {
		if(scm == null) {
			scm = new SentenceCountManager(this);
		}
		return scm;
	}
	
	public Token getTokenWithIndex(int index)  {
			TokenIterator tokenIterator = new TokenIterator(this);
			while(tokenIterator.hasNext()) {
				Token token = tokenIterator.next();
				if(token.getIndex()==index) {
					return token;
				}
				
			}
			throw new IndexOutOfBoundsException("Index is out of bounds");
	}
	
	public void assignPosTagsToTokens(String inputFile) throws IOException{
		ArrayList<Token> tokens = Tokenizer.tokenizeTaggedFile(new File(inputFile));
		TokenIterator tokenIterator = getTokenIterator();
		int globalCounter = 0;
		while(tokenIterator.hasNext()) {
			Token t = tokenIterator.next();
			if(Token.isNumber(t.getOrginal())){
				int c = t.getOrginal().trim().split(" ").length;
				globalCounter+=(c-1);
				t.setPOSTag(POSTag.NUMBER);
			}
			else{
				t.assignPosTag(tokens.get(t.getIndex()+globalCounter));
			}
		}
	}
		
	public void printDocument(){
		for(Section s: this){
			s.print();
			System.out.println("------------");
		}
	}
	
	public void printDocumentWithIDs(){
		System.out.println("Document ID: " + id);
		for(Section s: this){
			System.out.println("   Section ID: " + s.getId());
			for(Sentence sentence: s){
				System.out.println("      Sentence ID: " + sentence.getIndex());
				for(Token t: sentence){
					System.out.println("          Token ID " + t.getIndex() + " " + t + " " + t.getStripped() +" " +t.getPOSTag());
				}
			}
		}
	}
	
	public void prepareTokens() {
		TokenIterator tokenIterator = getTokenIterator();
		while(tokenIterator.hasNext()) {
			if (Constants.ENABLE_PREPARE_TOKEN) {
				PreRuleBase.prepareToken(tokenIterator.next());
			}
		}
	}
		
	public static int getAndIncreaseTokenIndex(){
		return tokenIndex++;
	}
	
	public static int getAndIncreaseSentenceIndex(){
		return sentenceIndex++;
	}
	
	public static int getAndIncreaseSectionIndex(){
		return sectionIndex++;
	}
		
	public CountManager getWordCountManager(){
		if(wcm == null) {
			wcm = new WordCountManager(this);
		}
		return wcm;
	}
	
	public TokenIterator getTokenIterator() {
		return new TokenIterator(this);
	}	
}
